package org.example.config;

import org.example.filter.JwtAuthenticationTokenFilter;
import org.example.handler.AccessDeniedHandlerImpl;
import org.example.handler.AuthenticationEntryPointImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.annotation.Resource;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
	@Resource
	private AuthenticationEntryPointImpl authenticationEntryPointImpl;
	@Resource
	private AccessDeniedHandlerImpl accessDeniedHandlerImpl;
	@Resource
	private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;

	//注明密码加密方式，使用BCryptPasswordEncoder
	@Bean
	public PasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();
	}

	//配置认证管理器，使用自定义的认证管理器
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http
				.headers().frameOptions().disable()
				.and()
				//关闭csrf
				.csrf().disable()
				//不通过session获取SecurityContext
				.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
				.and()
				.authorizeRequests()
				//对于登录接口 允许匿名访问 放行
				//anonymous() 允许匿名用户访问,不允许已登入用户访问
				//permitAll() 不管登入,不登入 都能访问
//				.antMatchers("/**").permitAll();
				.antMatchers("/fileTest").permitAll()
				.antMatchers("/doc.html", "/webjars/**", "/v2/**",
						"/swagger-resources/**", "/api/{apiKey}", "/file/{fileId}").permitAll()
				//其他接口需要认证
				.anyRequest().authenticated();
		//把token校验过滤器添加到过滤器链中
		http.addFilterBefore(this.jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
		//配置异常处理器
		http.exceptionHandling().authenticationEntryPoint(this.authenticationEntryPointImpl);
		//配置授权处理器
		http.exceptionHandling().accessDeniedHandler(this.accessDeniedHandlerImpl);
		//允许跨域访问
		http.cors();
	}

	//重写方法，用于把AuthenticationManager注入到SecurityContext

	@Override
	@Bean
	public AuthenticationManager authenticationManagerBean() throws Exception {
		return authenticationManager();
	}
}